import { effect } from './effect/effect.js'
import track from './effect/track.js'
import trigger from './effect/trigger.js'
import { TrackOpTypes, TriggerOpTypes } from './utils.js'
/**
 * 参数归一化处理
 * @param {*} getterOrOptions
 * @returns
 */
function normalizeParameter(getterOrOptions) {
  let getter, setter
  if (typeof getterOrOptions === 'function') {
    getter = getterOrOptions
    setter = () => {
      console.log('Computed property was addigned to but it has no setter')
    }
  } else {
    getter = getterOrOptions.get
    setter = getterOrOptions.set
  }
  return { getter, setter }
}

/**
 *
 * @param {*} getterOrOptions 函数或者对象
 */
export function computed(getterOrOptions) {
  // 参数归一化
  let { getter, setter } = normalizeParameter(getterOrOptions)

  let value // 存储计算属性的值
  let dirty = true // 表示计算属性是否脏，如果为 true，说明需要重新计算

  const effectFn = effect(getter, {
    lazy: true,
    shcheduler() {
      // 当响应式数据发生变化的时候
      dirty = true
      trigger(obj, TriggerOpTypes.SET, 'value')
    }
  })

  const obj = {
    // 外部获取计算属性的值
    get value() {
      // 进行依赖收集
      track(obj, TrackOpTypes.GET, 'value')
      if (dirty) {
        value = effectFn()
        dirty = false
      }
      return value
    },
    set value(newValue) {
      setter(newValue)
    }
  }

  return obj
}
